import { ChangeDetectionStrategy, Component, forwardRef, Input, OnInit } from '@angular/core';
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CheckItem, CheckMode } from '../../form-group.interfaces';

@Component({
  selector: 'yby-checkbox-list',
  templateUrl: './checkbox.component.html',
  styleUrls: ['./checkbox.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CheckboxComponent),
      multi: true,
    }
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CheckboxComponent implements ControlValueAccessor, OnInit {

  @Input() data: CheckItem[] = [];
  @Input() mode: CheckMode = CheckMode.list;
  form: FormGroup = new FormGroup({});

  private _onChange = (_: any) => { };

  constructor(
    private fb: FormBuilder,
  ) { }

  reGroupValues(values: CheckItem[]) {
    let aMode = '';
    if (typeof this.mode !== 'string') {
      aMode = 'list';
    } else {
      aMode = this.mode;
    }
    let data;
    data = this.data.map((item, index) => {
      return {
        ...item,
        checked: values[index],
      };
    }).filter(item => item.checked).map(item => ({ label: item.label, value: item.value }));
    if (aMode === CheckMode.all) {
      return data;
    }
    data = data.map(item => item.value);
    if (aMode === CheckMode.list) {
      return data;
    }
    if (aMode === CheckMode.str) {
      return data.join(',');
    }
    return '';
  }

  resetCpValue(values: any) {
    let aMode = '';
    if (typeof this.mode !== 'string') {
      aMode = 'list';
    } else {
      aMode = this.mode;
    }
    const cpValue: any = {};
    if (aMode === CheckMode.all) {
      this.data.forEach((item, index) => {
        cpValue[index] = values.filter((aItem: CheckItem) => item.value === aItem.value).length > 0 ? true : false;
      });
    } else if (aMode === CheckMode.list) {
      this.data.forEach((item, index) => {
        cpValue[index] = values.indexOf(item.value) > -1 ? true : false;
      });
    } else if (aMode === CheckMode.str ) {
      values = values.split(',');
      this.data.forEach((item, index) => {
        cpValue[index] = values.indexOf(item.value) > -1 ? true : false;
      });
    }
    return cpValue;
  }

  ngOnInit() {
    const options: any = {};
    this.data.forEach((item, index) => {
      options[index] = [!item.checked ? false : true];
    });
    this.form = this.fb.group(options);
    // 监听控件的每一个元素change事件，然后调用 _onChange
    this.form.valueChanges.subscribe(values => {
      this._onChange(this.reGroupValues(values));
    });
  }

  // 向控件form中写入values-form通过setValue,patchValue给form赋值的时候
  writeValue(values: any) {
    if (!values) {
      return;
    }
    const cpValue: any = {};
    this.data.forEach((item, index) => {
      cpValue[index] = values.indexOf(item.value) > -1 ? true : false;
    });
    this.form.setValue(cpValue);
  }

  // 注册空间change事件-用于外部form对该控件的监听
  registerOnChange(fn: any) {
    this._onChange = fn;
  }

  registerOnTouched(fn: any) {
    // 此组件是否触碰可以不设置，无实际意思
    // 如果是封装的输入元素可以设置此操作，并在组件中某些输入blur事件中调用 _onTouched 来进行触发
    // eg this._onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    // 因为当前组件为check的组合，每个元素都可以进行disable设置，故此可以调用form的方法
    if (isDisabled) {
      this.form.disable();
    } else {
      this.form.enable();
    }
  }

}
